package cn.com.libertymutual.core.sftp;

import java.io.File;
import java.io.InputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import com.google.common.base.Strings;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

@Component
public class SFtpClient implements ISFtpClient {
	private Logger log = LoggerFactory.getLogger(getClass());
	
	private SFtpConfig sftpConfig;
	
	public SFtpConfig getSftpConfig() {
		return sftpConfig;
	}

	public void setSftpConfig(SFtpConfig sftpConfig) {
		this.sftpConfig = sftpConfig;
	}

	public void init() {
		log.info("Init sftpClient...");
		log.info( sftpConfig.getPassword() );
		
		sftpConfig.setPassword( new String( Base64Utils.decodeFromString( sftpConfig.getPassword() ) ) );
	}
	
	public void destroy() {
		log.info("SFtpClient destroy...");
		sftpConfig = null;
	}

	@Override
	public ChannelSftp connect() throws JSchException, SftpException {
		JSch jsch = new JSch();

		Session sshSession = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getHost(), sftpConfig.getPort());
		
		//System.out.println("Session created.");
		sshSession.setPassword( sftpConfig.getPassword() );
		sshSession.setConfig("userauth.gssapi-with-mic", "no");
		
		Properties sshConfig = new Properties();
		sshConfig.put("StrictHostKeyChecking", sftpConfig.getStrictHostKeyChecking());
		
		sshSession.setConfig(sshConfig);
		//sshSession.connect();
		
		log.info("开始连接文件服务器");
		sshSession.connect(sftpConfig.getConnectTimeout());

		ChannelSftp sftp = (ChannelSftp) sshSession.openChannel("sftp");
		sftp.connect( sftpConfig.getConnectTimeout() );
		
		log.info("文件服务器连接成功");
		
		if( !Strings.isNullOrEmpty( sftpConfig.getLocalDirectory() ) )
			sftp.lcd( sftpConfig.getLocalDirectory() );
		
		if( !Strings.isNullOrEmpty( sftpConfig.getRemoteDirectory() ) )
			sftp.cd( sftpConfig.getRemoteDirectory() );
		
		return sftp;
	}
	
	/**
	 * 
	 * @update 2016-05-19 15:30 zhaoyu
	 * 
	 * @throws Exception
	 * 
	 * **/
	
	@SuppressWarnings("unused")
	@Deprecated
	private void mkdirs( ChannelSftp sftp, String dirs ) throws Exception{
		String dirArray[] = null;
		
		if( !Strings.isNullOrEmpty( dirs ) ) {
			dirArray = dirs.split( sftpConfig.getRemoteFileSeparator() );
			
			for (String dir : dirArray) {
				sftp.mkdir( dir );
			}
		}
	}
	
//	private void cds( ChannelSftp sftp, String dirs ) throws SftpException {
//		if( !Strings.isNullOrEmpty( dirs ) ) {
//			boolean isCdSuccess = true;
//			try {
//				sftp.cd( dirs );
//				return;
//			} catch (SftpException e2) {
//				isCdSuccess = false;
//			}
//			
//			if( !isCdSuccess ) {
//				String dirArray[] = dirs.split( sftpConfig.getRemoteFileSeparator() );
//	
//				for (String dir : dirArray) {
//					if( Strings.isNullOrEmpty( dir) ) continue;
//					
//					try {
//						sftp.cd( dir );
//					} catch (SftpException e) {
//						if(ChannelSftp.SSH_FX_NO_SUCH_FILE == e.id){
//							try {
//								sftp.mkdir(dir);
//								sftp.cd( dir );
//							} catch (SftpException e1) {
//								log.error(dir, e1);
//							}
//						}
//						else throw e;
//					}
//				}
//			}
//		}
//	}
	
//	private void cds( ChannelSftp sftp, String dirs ) throws SftpException {
//		if( !Strings.isNullOrEmpty( dirs ) ) {
//			boolean isCdSuccess = true;
//			try {
//				sftp.cd( dirs );
//				return;
//			} catch (SftpException e2) {
//				isCdSuccess = false;
//			}
//			StringBuilder path = new StringBuilder(dirs.substring(0, dirs.indexOf("sftp/")+5));
//			String parampath = dirs.substring(dirs.indexOf("sftp/")+5, dirs.length());
//			
//			if( !isCdSuccess ) {
//				String dirArray[] = parampath.split( sftpConfig.getRemoteFileSeparator() );
//				for (String dir : dirArray) {
//					log.info("-------jinru目录---------------:"+dir);
//										
//					if( Strings.isNullOrEmpty( dir) ) continue;
//					
//					path.append(dir+"/");
//					try {
//						sftp.cd( path.toString() );
//					} catch (SftpException e) {
//						if(ChannelSftp.SSH_FX_NO_SUCH_FILE == e.id){
//							try {
//								sftp.mkdir(path.toString());
//								log.info("-------创建不存在的目录---------------:"+dir);
////								sftp.cd( dir );
//							} catch (SftpException e1) {
//								log.error(dir, e1);
//							}
//						}
//						else throw e;
//					}
//				}
//				sftp.cd( path.toString() );
//			}
//		}
//	}
	
	
	
	private void cds( ChannelSftp sftp, String dirs ) throws SftpException {
		if( !Strings.isNullOrEmpty( dirs ) ) {
			boolean isCdSuccess = true;
			try {
				sftp.cd( dirs );
				return;
			} catch (SftpException e2) {
				isCdSuccess = false;
			}
			StringBuilder path = new StringBuilder("/");
			
			if( !isCdSuccess ) {
				String dirArray[] = dirs.split( sftpConfig.getRemoteFileSeparator() );
				for (String dir : dirArray) {
					log.info("-------jinru目录---------------:"+dir);
					path.append(dir+"/");			
					if( Strings.isNullOrEmpty( dir) ) continue;
					
					try {
						sftp.cd( path.toString() );
					} catch (SftpException e) {
						if(ChannelSftp.SSH_FX_NO_SUCH_FILE == e.id){
							try {
								sftp.mkdir(path.toString());
								log.info("-------创建不存在的目录---------------:"+dir);
							} catch (SftpException e1) {
								log.error(dir, e1);
							}
						}
						else throw e;
					}
				}
				log.info("最终路径----{}"+path.toString());
				sftp.cd( path.toString() );
			}
		}
	}
	
	/**
	 * @update 2016-05-19 15:32 zhaoyu
	 * 
	 * @throws Exception
	 * 
	 * */
	@Override
	public boolean putFile( String fileName, String dirs ) throws Exception{
		ChannelSftp sftp = null;
		
		try {
			sftp = connect();
			
			cds( sftp, dirs );
			
			sftp.put(fileName, new File(fileName).getName());
			
			return true;

		}finally {
			if( sftp != null ) {
				Session session = sftp.getSession();
				if( session.isConnected() ) {
					session.disconnect();
				}
				sftp.exit();
			}
		}
	}
	
	/**
	 * 
	 * @update 2016-05-19 15:33 zhaoyu
	 * 
	 * 
	 * @throws Exception
	 * 
	 * */
	@Override
	public boolean putFile( String fileName ) throws Exception{
		return putFile(fileName, null);
	}
	
	
	/**
	 * 
	 * @update 2016-05-19 15:33 zhaoyu
	 * 
	 * 
	 * @throws Exception
	 * 
	 * */	
	@Override
	public boolean putFile( InputStream src, String fileName, String dirs ) throws Exception{
		ChannelSftp sftp = null;
		
		try {
			sftp = connect();
			
			sftp.cd( sftpConfig.getRemoteDirectory() );
			
			cds( sftp, dirs );
			
			sftp.put(src, fileName);

			return true;
		
		}finally {
			if( sftp != null ) sftp.exit();
		}
		
		
	}

	/**
	 * 
	 * @throws Exception 
	 * @update 2016-05-19 15:33 zhaoyu
	 * 
	 * 
	 * 
	 * 
	 * */
	@Override
	public boolean putFile( InputStream src, String fileName ) throws Exception {
		return putFile(src, fileName, null);
	}
	

}
